﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp6
{
    public class FileCheckpoint : ICheckPoint
    {
        public string Name { get; }
        private long _last;
        private long _lastFlushed;
        private Stream _fileStream;
        private BinaryWriter _writeStream;
        public FileCheckpoint(string name)
        {
            Name = name;
            _fileStream = new FileStream(Name, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
            _fileStream.SetLength(sizeof(long));
            _writeStream = new BinaryWriter(_fileStream);
        }

        public long Read()
        {
            return Interlocked.Read(ref _lastFlushed);
        }

        public long ReadNonFlushed()
        {
            return Interlocked.Read(ref _last);
        }

        public void Write(long checkpoint)
        {
            Interlocked.Exchange(ref _last, checkpoint);
        }

        public void Flush()
        {
            var last = Interlocked.Read(ref _last);
            if (last == _lastFlushed)
                return;
            _writeStream.Write(_last);
            _writeStream.Flush();
            Interlocked.Exchange(ref _lastFlushed, last);
            Flushed(last);
        }

        public void Close()
        {
            _writeStream.Close();
            _fileStream.Close();
        }

        public event Action<long>? Flushed;
    }
}
